﻿using CodePlex.TfsPluginSuite.Configuration;
using CodePlex.TfsPluginSuite.Configuration.PatternBypassOverride;
using CodePlex.TfsPluginSuite.Helper;
using Microsoft.TeamFoundation.Common;
using Microsoft.TeamFoundation.Framework.Server;
using Microsoft.TeamFoundation.VersionControl.Server;
using System;
using System.Linq;

namespace CodePlex.TfsPluginSuite.Overrides
{
    public class AccountOverride : ISubscriber
    {
        public string Name => typeof(AccountOverride).FullName;

        public SubscriberPriority Priority => SubscriberPriority.High;

        public EventNotificationStatus ProcessEvent(IVssRequestContext requestContext,
            NotificationType notificationType,
            object notificationEventArgs,
            out int statusCode,
            out string statusMessage,
            out ExceptionPropertyCollection properties)
        {
            properties = new ExceptionPropertyCollection();
            statusMessage = String.Empty;
            statusCode = 0;

            // If this is a check-in notification and is a decision point
            if (notificationEventArgs is CheckinNotification && notificationType == NotificationType.DecisionPoint)
            {
                // run if enabled
                var config = TfsPluginSuiteConfigurationManager.Section.AccountOverride;
                if (config.Enabled)
                {
                    try
                    {
                        CheckinNotification notification = notificationEventArgs as CheckinNotification;

                        using (var tfsHelper = new TfsHelper(requestContext, notification))
                        {
                            foreach (AccountOverrideConfigElement group in config)
                            {
                                string groupName = group.Name.Replace("@ProjectCollection", requestContext.ServiceHost.Name);
                                if (tfsHelper.IsInGroup(groupName, notification.ChangesetOwner.Descriptor) && SatisfiesCheckNote(group, notification))
                                {
                                    return EventNotificationStatus.ActionApproved;
                                }
                            }
                        }

                    }
                    catch (Exception e)
                    {
                        statusCode = -1;
                        statusMessage += e.ToString();
                        requestContext.Status = e;
                    }
                }

            }
            return EventNotificationStatus.ActionPermitted;
        }

        public Type[] SubscribedTypes()
        {
            return new[] { typeof(CheckinNotification) };
        }

        private static bool SatisfiesCheckNote(AccountOverrideConfigElement groupConfig, CheckinNotification notification)
        {
            if (groupConfig.RequireCheckinNote)
            {
                if (notification.CheckinNote != null && notification.CheckinNote.Values != null)
                {
                    //try to get the checkin note
                    CheckinNoteFieldValue checkinNote = notification.CheckinNote.Values.AsEnumerable().FirstOrDefault(note => note.Name.Equals(groupConfig.CheckinNoteName));
                    //if the checkin note type exists then it will not be null, then make sure something was entered                           
                    return (checkinNote != null && !string.IsNullOrWhiteSpace(checkinNote.Value));
                }
                else
                {
                    return false;
                }
            }
            else     // if its not required, then its satisfied
            {
                return true;
            }
        }
    }
}